package com.zlk.algorithm.dataStructure.graph.topological;

import com.zlk.algorithm.dataStructure.graph.impl.Graph;
import com.zlk.algorithm.dataStructure.graph.impl.Node;

import java.util.*;

/**
 * @program: algorithm
 * @ClassName TopologySort
 * @description:
 * @author: slfang
 * @create: 2024-03-19 19:15
 * @Version 1.0
 **/
public class TopologySort {



    //以上方法会将原数据修改吊
    public static void sort(Graph graph){
        HashMap<Integer, Node> nodeHashMap = graph.nodes;
        Queue<Node> zeroQueue = new LinkedList<>();
        for (Integer s : nodeHashMap.keySet()) {
            Node node = nodeHashMap.get(s);
            if(node.in==0){
                zeroQueue.add(node);
            }
        }
        List<Node> ans = new ArrayList<>();
        while (!zeroQueue.isEmpty()){
            Node cur = zeroQueue.poll();
            ans.add(cur);
            for (Node next : cur.nexts) {
                next.in--;
                if(next.in==0){
                    zeroQueue.add(next);
                }
            }
        }
    }

    public static List<Node> sortedTopology(Graph graph) {
        // key 某个节点   value 剩余的入度
        HashMap<Node, Integer> inMap = new HashMap<>();
        // 只有剩余入度为0的点，才进入这个队列
        Queue<Node> zeroInQueue = new LinkedList<>();
        for (Node node : graph.nodes.values()) {
            inMap.put(node, node.in);
            if (node.in == 0) {
                zeroInQueue.add(node);
            }
        }
        List<Node> result = new ArrayList<>();
        while (!zeroInQueue.isEmpty()) {
            Node cur = zeroInQueue.poll();
            result.add(cur);
            for (Node next : cur.nexts) {
                inMap.put(next, inMap.get(next) - 1);
                if (inMap.get(next) == 0) {
                    zeroInQueue.add(next);
                }
            }
        }
        return result;
    }
}
